#include "ROExportProperty.h"
#include "ROSignalConnection.h"

ROExportProperty::ROExportProperty(QObject *parent):ROSharedObject(parent)
{

}

QObject *ROExportProperty::target() const
{
    return m_target;
}

void ROExportProperty::setTarget(QObject *newTarget)
{
    if (m_target == newTarget)
        return;
    m_target = newTarget;
    validate();
    emit targetChanged();
}

void ROExportProperty::initialize()
{
    ROSharedObject::initialize();
    validate();
}

QStringList ROExportProperty::properties() const
{
    return m_properties;
}

void ROExportProperty::setProperties(const QStringList &newProperties)
{
    if (m_properties == newProperties)
        return;
    m_properties = newProperties;
    validate();
    emit propertiesChanged();
}

QStringList ROExportProperty::allProperties()
{
    auto ret = ROSharedObject::allProperties();
    ret << m_properties;
    return ret;
}

QVariantMap ROExportProperty::extractProperties(const QStringList &prop)
{
    auto ret = ROSharedObject::extractProperties(prop);

    if(m_target)
    {
        auto meta = m_target->metaObject();

        for(auto i:prop)
        {
            if(m_properties.contains(i) && meta->indexOfProperty(i.toUtf8()) != -1)
            {
                ret[i] = m_target->property(i.toUtf8());
            }
        }
    }

    return ret;
}

void ROExportProperty::handleProperties(const QVariantMap &var)
{
    ROSharedObject::handleProperties(var);

    if(m_target)
    {
        auto meta = m_target->metaObject();
        for(auto i:var.keys())
        {
            if(m_properties.contains(i) && meta->indexOfProperty(i.toUtf8()) != -1)
            {
                updateTargetProperty(m_target,i,var[i]);
            }
        }
    }

}

void ROExportProperty::validate()
{
    if(role() == None)
    {
        return;
    }

    if(!m_ckeeper)
    {
        delete m_ckeeper;
    }

    if(!m_target)
    {
        return;
    }

    m_ckeeper = new QObject(this);

    auto meta = m_target->metaObject();

    if(role() == Host)
    {
        for(auto i:m_properties)
        {
            auto prop = meta->property(meta->indexOfProperty(i.toUtf8()));
            if(!prop.hasNotifySignal()) continue;
            std::function<void()> func = [=](){
                propertyChanged(i);
            };
            func();
            ROSignalConnection::connect(m_target,prop.notifySignalIndex()).to(m_ckeeper).on(func,Qt::AutoConnection);
        }
    }
}

ROExportProperty *SharedProperty::qmlAttachedProperties(QObject *object)
{
    auto ret = new ROExportProperty(object);
    ret->setTarget(object);
    return ret;
}
